package com.sy.server.service.impl;

import com.sy.server.dto.CostDTO;
import com.sy.server.dto.CostList;
import com.sy.server.dto.CostWithoutDetail;
import com.sy.server.mapper.CostMapper;
import com.sy.server.mapper.CostWithStrMapper;
import com.sy.server.mapper.CostWithoutDetailMapper;
import com.sy.server.model.Cost;
import com.sy.server.model.CostExample;
import com.sy.server.model.CostKey;
import com.sy.server.service.ICostService;
import com.sy.server.vo.CostWithStr;
import com.sy.server.vo.Day;
import com.sy.server.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class CostService implements ICostService {
    private final Logger logger= LoggerFactory.getLogger(CostService.class);
    @Autowired
    private CostMapper mapper;

    @Autowired
    private CostWithStrMapper cmapper;

    @Autowired
    private CostWithoutDetailMapper cwmapper;

    @Autowired
    private IpService ipService;

    /**
     * 已废弃
     * @param year
     * @return
     */
    @Deprecated
    public List<Cost> getYearTotalPay(Integer year) {
        String beginDate=DateUtil.getBeginEndDay(year,1)[0];
        String endDate=DateUtil.getBeginEndDay(year,12)[1];
        CostExample example=new CostExample();
        example.createCriteria().andDayBetween(beginDate,endDate);
        List<Cost> list=mapper.selectByExample(example);
        list.forEach(this::convert);
        return list;
    }

    public void del(String day) {
        CostKey key=new CostKey();
        Integer userId= ipService.getUserIdByCurrentIp();
        key.setDay(day);
        key.setUserId(userId);
        if(mapper.deleteByPrimaryKey(key)>0){
            logger.info("删除成功，用户id【{}】删除的记录日期为：{}",userId,day);
        }else{
            logger.error("删除失败");
        }
    }

    /**
     * 判断要加入的时间存不存在
     * @param date
     * @return
     */
    public boolean verifyDate(String date) {
        Integer userId=ipService.getUserIdByCurrentIp();
        CostExample example=new CostExample();
        example.createCriteria().andDayEqualTo(date).andUserIdEqualTo(userId);
        return mapper.countByExample(example)>0;
    }

    public void add(Cost cost) {
        Integer userId= ipService.getUserIdByCurrentIp();
        cost.setUserId(userId);
        mapper.insert(cost);
        logger.info("用户【{}】增加了一条数据",userId);
    }

    public void updateByDate(CostWithStr costWithStr) {
        Integer userId= ipService.getUserIdByCurrentIp();
        costWithStr.setUserId(userId);
        cmapper.updateByDate(costWithStr);
        logger.info("用户【{}】更新了一条数据",userId);
    }

    /**
     * 根据给定的年、月，查询总支出
     * @param year
     * @param month
     * @return
     */
    @Deprecated
    public double getTotalPay(Integer year,Integer month) {
        Integer userId= ipService.getUserIdByCurrentIp();
        List<Double> sumList=mapper.selectTotal(userId,DateUtil.processingParams(year,month)[0],DateUtil.processingParams(year, month)[1]);
        return sumList.stream().mapToDouble(Double::doubleValue).sum();
    }

    /**
     * 查询指定年月的支出列表，若不指定年月，则视为查询所有；
     * 若只指定年，则视为查询某一年所有月；不允许只指定月而不指定年
     * @param year
     * @param month
     * @return
     */
    public List<Cost> queryPayList(Integer year, Integer month) {
        List<Cost> list=null;
        CostExample example=new CostExample();
        example.createCriteria().andUserIdEqualTo(ipService.getUserIdByCurrentIp()).andDayBetween(DateUtil.processingParams(year,month)[0],DateUtil.processingParams(year, month)[1]);
        list=mapper.selectByExample(example);
        list.forEach(this::convert);
        return list;
    }

    /**
     * 支出为0的部分，在详情里补充 “无xx支出”
     * @param c
     */
    private void convert(Cost c){
        Cost cost=new Cost();
        c.setEatDetail(c.getEat()==0?cost.getEatDetail():c.getEatDetail());
        c.setHouseDetail(c.getHouse()==0?cost.getHouseDetail():c.getHouseDetail());
        c.setCommunicationDetail(c.getCommunication()==0?cost.getCommunicationDetail():c.getCommunicationDetail());
        c.setTrafficDetail(c.getTraffic()==0?cost.getTrafficDetail():c.getTrafficDetail());
        c.setDailyDetail(c.getDaily()==0?cost.getDailyDetail():c.getDailyDetail());
        c.setEducationDetail(c.getEducation()==0?cost.getEducationDetail():c.getEducationDetail());
        c.setClothesDetail(c.getClothes()==0?cost.getClothesDetail():c.getClothesDetail());
        c.setSnacksDetail(c.getSnacks()==0?cost.getSnacksDetail():c.getSnacksDetail());
        c.setFruitsDetail(c.getFruits()==0?cost.getFruitsDetail():c.getFruitsDetail());
        c.setMedicalDetail(c.getMedical()==0?cost.getMedicalDetail():c.getMedicalDetail());
        c.setOthersDetail(c.getOthers()==0?cost.getOthersDetail():c.getOthersDetail());
        c.setTodayEvent(c.getTodayEvent().equals("")?cost.getTodayEvent():c.getTodayEvent());
    }

    public List<String> getXDays(Day day){
        List<String> list=new ArrayList<>();
        int year=day.getYear();
        int month=day.getMonth();
        int today=day.getDay();
        int targetDays=day.getTargetDays();
        int days;
        if(today<=targetDays){
            days=DateUtil.getDays(year,month>1?month-1:12);
            int beginDateDay=days-targetDays+today;
            if(month==1 && year-1>=2000){
                for(int i=beginDateDay;i<=days;i++){
                    list.add(DateUtil.daysToString(year-1,12,i));
                }
                for(int i=1;i<=today-1;i++){
                    list.add(DateUtil.daysToString(year,1,i));
                }
            }else if(month>1){
                for(int i=beginDateDay;i<=days;i++){
                    list.add(DateUtil.daysToString(year,month-1,i));
                }
                for(int i=1;i<=today-1;i++){
                    list.add(DateUtil.daysToString(year,month,i));
                }
            }else{
                for(int i=1;i<=today-1;i++){
                    list.add(DateUtil.daysToString(2000,1,i));
                }
            }
        }else{
            for(int i=today-targetDays;i<=today-1;i++){
                list.add(DateUtil.daysToString(year,month,i));
            }
        }
        return list;
    }

    public Double getXDaysAvg(Day day){
        String beginDate="",endDate="";
        if(day.getTargetDays()==0){
            beginDate=DateUtil.processingParams(day.getYear(),day.getMonth())[0];
            endDate=DateUtil.processingParams(day.getYear(),day.getMonth())[1];
        }else{
            beginDate=getXDays(day).get(0);
            endDate=getXDays(day).get(day.getTargetDays()-1);
        }
        CostExample example=new CostExample();
        example.createCriteria().andUserIdEqualTo(ipService.getUserIdByCurrentIp()).andDayBetween(beginDate,endDate);
        double avg;
        if(mapper.countByExample(example)>0){
            avg=mapper.selectXDaysAvg(ipService.getUserIdByCurrentIp(),beginDate,endDate);
            return Double.parseDouble(String.format("%.2f",avg));
        }
        return 0.0;
    }

    public List<Double> getTotalPayList(Day day) {
        List<String> xdays=getXDays(day);
        int targetDays=day.getTargetDays();
        //2020-01-03
        String beginDate=xdays.get(0);
        String endDate=xdays.get(targetDays-1);
        List<CostDTO> dtoList=mapper.selectTotalWithDay(ipService.getUserIdByCurrentIp(),beginDate,endDate);
        List<Double> resList=new ArrayList<>(targetDays);
        int i=0,j=0;
        while(i<targetDays && j<targetDays){
            if(i<dtoList.size() && dtoList.get(i).getDay().equals(xdays.get(j))){
                resList.add(dtoList.get(i).getSum());
                i++;j++;
            }else{
                resList.add(0.0);
                j++;
            }
        }
        return resList;
    }

    public CostList queryPayListWithoutDetail(Day day) {
        int targetDays=day.getTargetDays();
        List<String> xdays=getXDays(day);
        String beginDate=xdays.get(0);
        String endDate=xdays.get(targetDays-1);
        List<CostWithoutDetail> cwdList=cwmapper.selectByBeginEndDay(ipService.getUserIdByCurrentIp(),beginDate,endDate);
        List<Double> eatList=new ArrayList<>(targetDays);
        List<Double> houseList=new ArrayList<>(targetDays);
        List<Double> communicationList=new ArrayList<>(targetDays);
        List<Double> trafficList=new ArrayList<>(targetDays);
        List<Double> dailyList=new ArrayList<>(targetDays);
        List<Double> educationList=new ArrayList<>(targetDays);
        List<Double> clothesList=new ArrayList<>(targetDays);
        List<Double> snacksList=new ArrayList<>(targetDays);
        List<Double> fruitsList=new ArrayList<>(targetDays);
        List<Double> medicalList=new ArrayList<>(targetDays);
        List<Double> othersList=new ArrayList<>(targetDays);
//        List<Double> sumList=new ArrayList<>(targetDays);
        int i=0,j=0;
        while(i<targetDays && j<targetDays){
            CostWithoutDetail l=null;
            if(i<cwdList.size() && (l=cwdList.get(i)).getDay().equals(xdays.get(j))){
                eatList.add(l.getEat());
                houseList.add(l.getHouse());
                communicationList.add(l.getCommunication());
                trafficList.add(l.getTraffic());
                dailyList.add(l.getDaily());
                educationList.add(l.getEducation());
                clothesList.add(l.getClothes());
                snacksList.add(l.getSnacks());
                fruitsList.add(l.getFruits());
                medicalList.add(l.getMedical());
                othersList.add(l.getOthers());
//                sumList.add(l.getSum());
                i++;j++;
            }else{
                eatList.add(0.0);
                houseList.add(0.0);
                communicationList.add(0.0);
                trafficList.add(0.0);
                dailyList.add(0.0);
                educationList.add(0.0);
                clothesList.add(0.0);
                snacksList.add(0.0);
                fruitsList.add(0.0);
                medicalList.add(0.0);
                othersList.add(0.0);
//                sumList.add(0.0);
                j++;
            }
        }
        CostList costList=new CostList();
        costList.setEatList(eatList);
        costList.setHouseList(houseList);
        costList.setCommunicationList(communicationList);
        costList.setTrafficList(trafficList);
        costList.setDailyList(dailyList);
        costList.setEducationList(educationList);
        costList.setClothesList(clothesList);
        costList.setSnacksList(snacksList);
        costList.setFruitsList(fruitsList);
        costList.setMedicalList(medicalList);
        costList.setOthersList(othersList);
//        costList.setSumList(sumList);
        return costList;
    }

    public CostWithoutDetail sumEachOther(Integer year, Integer month){
        String beginDate=DateUtil.processingParams(year,month)[0];
        String endDate=DateUtil.processingParams(year,month)[1];
        Integer userId= ipService.getUserIdByCurrentIp();
        CostWithoutDetail cwd1=cwmapper.getSumEachOther(userId,beginDate,endDate);
        if(cwd1==null){
            return new CostWithoutDetail();
        }
        return cwd1;
    }
}
